import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import java.util.List;

/**
 * The View of the Battleship game comprised of the GUI and updates to the state
 * of the game are reflected by the view.
 * 
 * @author Vo, Wu and Wyan
 * 
 */
public class BattleshipView extends JFrame {

	/**
	 * The width of the View window.
	 */
	private static final int WIDTH = 1100;
	
	/**
	 * The height of the View window.
	 */
	private static final int HEIGHT = 660;
	
	/**
	 * The font size of the title label.
	 */
	private static final int TITLE_SIZE = 42;
	
	/**
	 * The font size of the status indicator label.
	 */
	private static final int FONT_SIZE = 24;
	
	/**
	 * Label that updates to inform the user about what is going on in the game.
	 */
	private JLabel statusIndicator = new JLabel(
			"Player 1, place your aircraft carrier!");

	/**
	 * Label that contains the title of the game.
	 */
	private JLabel title = new JLabel("~Battleship~");
	
	/**
	 * Button grids for player 1.
	 */
	private ButtonGrid p1Grid = new ButtonGrid();

	/**
	 * Button grids for player 2.
	 */
	private ButtonGrid p2Grid = new ButtonGrid();

	// Constructor
	/**
	 * Produces button grids for both players.
	 * 
	 * @ensures button grids = #10x10 grids
	 */
	public BattleshipView() {
		JPanel content = new JPanel();
		JPanel titlePanel = new JPanel();
		JPanel grid1 = new JPanel();
		JPanel grid2 = new JPanel();
		JPanel superGrid = new JPanel();
		
		//set preferences
		superGrid.setLayout(new GridLayout(1, 3));
		this.setLayout(new BorderLayout());
		this.setBounds(0, 0, WIDTH, HEIGHT);
		this.statusIndicator.setFont(new Font("Monospaced", Font.PLAIN, FONT_SIZE));
		this.title.setFont(new Font("SansSerif", Font.BOLD, TITLE_SIZE));
		
		//add components to the frames and panels
		content.add(statusIndicator);
		titlePanel.add(title);
		grid1.add(p1Grid.getFrame());
		superGrid.add(grid1);
		grid2.add(p2Grid.getFrame());
		superGrid.add(grid2);
		
		//add to the overall View.
		add(titlePanel, BorderLayout.NORTH);
		add(superGrid, BorderLayout.CENTER);
		add(content, BorderLayout.SOUTH);

		this.setTitle("Battleship");
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setVisible(true);
	}

	/**
	 * Saves the label of the cell clicked by the player.
	 * 
	 * @param p1Turn
	 *            Whether or not it is player 1's turn.
	 * @return The cell clicked on the grid corresponding to the turn boolean.
	 */
	public final String getClickedCell(Boolean p1Turn) {
		String cell = "";
		if (p1Turn) {
			cell = p1Grid.getClickedCell();
		} else {
			cell = p2Grid.getClickedCell();
		}
		return cell;
	}

	/**
	 * Allowing the button grids to be clicked by each player during his or her
	 * turn.
	 * 
	 * @param p1Turn
	 *            Whether or not it is player 1's turn.
	 */
	public final void enableGrid(Boolean p1Turn) {
		if (p1Turn) {
			p1Grid.enableButtons();
		} else {
			p2Grid.enableButtons();
		}
	}

	/**
	 * Allowing the button grids to be clicked by each player during his or her
	 * turn.
	 * 
	 * @param p1Turn
	 *            Whether or not it is player 1's turn.
	 */
	public final void disableGrid(Boolean p1Turn) {
		if (p1Turn) {
			p1Grid.disableButtons();
		} else {
			p2Grid.disableButtons();
		}
	}

	/**
	 * Highlight the end points of cell during ship placement for a player to
	 * choose.
	 * 
	 * @param p1Turn
	 *            Whether or not it is player 1's turn.
	 * @param endpoints
	 *            A collection of end points from ship placement for each player
	 */
	public final void highlightEndpoints(Boolean p1Turn, List<String> endpoints) {
		if (p1Turn) {
			for (String cell : endpoints) {
				p1Grid.highlightCell(cell);
			}
		} else {
			for (String cell : endpoints) {
				p2Grid.highlightCell(cell);
			}
		}
	}

	/**
	 * Dehighlight the end points of cell during ship placement for a player to
	 * choose.
	 * 
	 * @param p1Turn
	 *            Whether or not it is player 1's turn.
	 * @param endpoints
	 *            A collection of end points from ship placement for each
	 *            player.
	 */
	public final void dehighlightEndpoints(Boolean p1Turn,
			List<String> endpoints) {
		if (p1Turn) {
			for (String cell : endpoints) {
				p1Grid.dehighlightCell(cell);
			}
		} else {
			for (String cell : endpoints) {
				p2Grid.dehighlightCell(cell);
			}
		}
	}

	/**
	 * Updates the grid to highlight and color the cell according to its status.
	 * 
	 * @param p1Turn
	 *            Whether or not it is player 1's turn.
	 * @param cell
	 *            The cell to be updated.
	 * @param color
	 *            The key indicative of the highlight to be applied.
	 */
	public final void updateGrid(Boolean p1Turn, String cell, String color) {
		if (p1Turn) {
			p2Grid.changeColor(cell, color);
		} else {
			p1Grid.changeColor(cell, color);
		}
	}

	/**
	 * Update the label according to the status of the game.
	 * 
	 * @param text
	 *            Message that will print out to update the player during the
	 *            game.
	 */
	public final void updateLabel(String text) {
		statusIndicator.setText(text);
	}

	/**
	 * Adding the action listener.
	 * 
	 * @param click
	 *            The click action that occurs for each player.
	 */
	public final void addActionListener(ActionListener click) {
		p1Grid.addActionListener(click);
		p2Grid.addActionListener(click);
	}

}
